开发者

Is it possible to build an XML document from a list of XPath values and the XML XSD?

I have a list of name/value pairs that I would like to map into an XML document. My idea is this, assign each of the names an XPath like this:

Account_Number       = 4294587576-32      = /my:myFields/my:Customer/my:AccountNumber
Customer_Name        = John Smith         = /my:myFields/my:Customer/my:Name
Customer_Address     = Tampa, FL  33604   = /my:myFields/my:Customer/my:Address
Amount_Due           = 129.85             = /my:myFields/my:AmountDue/my:Amount
Days_Past_Due        = 54                 = /my:myFields/my:AmountDue/my:DaysPastDue

Now, shouldn't I be able to take this information along with a complete sample of the XML document or the XSD and build an XML document that looks something like this:

<my:myFields>
    <my:Customer>
        <my:Name>John Smith</my:Name>
        <my:AccountNumber>4294587576-32</my:AccountNumber>
        <my:Address>Tampa, FL  33604</my:Address>
    </my:Customer>
    <my:AmountDue>
        <my:DaysPastDue>54</my:DaysPastDue>
        <my:Amount>129.85</my:Amount>
    </my:AmountDue>
</my:myFields>

My question is specific to Microsoft InfoPath because I need to take the list of开发者_开发知识库 name/value pairs and build the XML data document for an InfoPath form. The technology that performs the translation does not have to be Microsoft. Java or C++ would be the best solution. Can this be done using an XSLT processor like Apache's Xalan?


Here is one suggestion, as you mention Java and XSLT I wouldn't bother with Xalan and XSLT 1.0 but instead use Saxon 9 and XSLT 2.0. Assuming you have an well-formed XML input sample and your above mapping of values to XPath expressions I would feed the mapping to an XSLT 2.0 stylesheet that generates a second stylesheet that can then be applied to the input sample. So assuming we have the file 'test2011101201.txt' as

Account_Number       = 4294587576-32      = /my:myFields/my:Customer/my:AccountNumber
Customer_Name        = John Smith         = /my:myFields/my:Customer/my:Name
Customer_Address     = Tampa, FL  33604   = /my:myFields/my:Customer/my:Address
Amount_Due           = 129.85             = /my:myFields/my:AmountDue/my:Amount
Days_Past_Due        = 54                 = /my:myFields/my:AmountDue/my:DaysPastDue

the stylesheet

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:axsl="http://www.w3.org/1999/XSL/Transforma"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:my="http://example.com/my"
  version="2.0"
  exclude-result-prefixes="xs">

  <xsl:param name="text-file" as="xs:string" select="'test2011101201.txt'"/>
  <xsl:variable name="lines" as="xs:string*" select="tokenize(unparsed-text($text-file), '\r?\n')[normalize-space()]"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>

  <xsl:template match="/">
    <axsl:stylesheet version="2.0">
      <axsl:template match="@* | node()">
        <axsl:copy>
          <axsl:apply-templates select="@*, node()"/>
        </axsl:copy>
      </axsl:template>
      <xsl:for-each select="$lines">
        <xsl:variable name="tokens" select="tokenize(., '=')"/>
        <axsl:template match="{normalize-space($tokens[3])}">
          <axsl:copy>
            <axsl:apply-templates select="@*"/>
            <axsl:text>
              <xsl:value-of select="replace($tokens[2], '(^\s+|\s+$)', '')"/>
            </axsl:text>
          </axsl:copy>
        </axsl:template>
      </xsl:for-each>
    </axsl:stylesheet>
  </xsl:template>

</xsl:stylesheet>

can be run to produce a second stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="http://example.com/my"
                version="2.0">
   <xsl:template match="@* | node()">
      <xsl:copy>
         <xsl:apply-templates select="@*, node()"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/my:myFields/my:Customer/my:AccountNumber">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:text>4294587576-32</xsl:text>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/my:myFields/my:Customer/my:Name">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:text>John Smith</xsl:text>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/my:myFields/my:Customer/my:Address">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:text>Tampa, FL  33604</xsl:text>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/my:myFields/my:AmountDue/my:Amount">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:text>129.85</xsl:text>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/my:myFields/my:AmountDue/my:DaysPastDue">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:text>54</xsl:text>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

which, when applied to an input sample like

<my:myFields xmlns:my="http://example.com/my">
    <my:Customer>
        <my:Name></my:Name>
        <my:AccountNumber></my:AccountNumber>
        <my:Address></my:Address>
    </my:Customer>
    <my:AmountDue>
        <my:DaysPastDue></my:DaysPastDue>
        <my:Amount></my:Amount>
    </my:AmountDue>
</my:myFields>

outputs

<?xml version="1.0" encoding="UTF-8"?><my:myFields xmlns:my="http://example.com/my">
    <my:Customer>
        <my:Name>John Smith</my:Name>
        <my:AccountNumber>4294587576-32</my:AccountNumber>
        <my:Address>Tampa, FL  33604</my:Address>
    </my:Customer>
    <my:AmountDue>
        <my:DaysPastDue>54</my:DaysPastDue>
        <my:Amount>129.85</my:Amount>
    </my:AmountDue>
</my:myFields>

As I said, that requires XSLT 2.0 and an XSLT 2.0 processor like Saxon 9 to parse the text file. And whoever authors that text file needs to make sure the path expressions that the stylesheet maps into XSLT match patterns are not ambiguous.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜