在XSL选择

时间:2016-01-28 09:54:55

标签: xml xslt xml-parsing

我有一个复杂的XML输入,我需要将其转换为平面结构,通过重复相关节点来解释XML文档中的树。

源XML看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="forom%20sample.xsl"?>
<Customers>
    <Customer>
        <ID>1</ID>
        <Name>John Madsen</Name>
        <Accounts>
            <Account>
                <ID>111</ID>
                <Name>AAA</Name>
                <Value>11234</Value>                
            </Account>
            <Account>
                <ID>222</ID>
                <Name>BBB</Name>
                <Value>64</Value>
            </Account>
        </Accounts>
        <Profile>
            <Gender>M</Gender>
            <Age>32</Age>
        </Profile>
    </Customer>

    <Customer>
        <ID>2</ID>
        <Name>Dona M. Graduate</Name>
        <Accounts>
            <Account>
                <ID>333</ID>
                <Name>CCC</Name>
                <Value>5215</Value>                
            </Account>
            <Account>
                <ID>555</ID>
                <Name>FFF</Name>
                <Value>6325</Value>
            </Account>
        </Accounts>
        <Profile>
            <Gender>F</Gender>
            <Age>36</Age>
        </Profile>
    </Customer>
</Customers>

所需的扁平结构应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Accounts>
  <Account>
     <CustomerID>1</CustomerID>
     <CustomerName>John Madsen</CustomerName>
     <ID>111</ID>
     <Name>AAA</Name>
     <Value>11234</Value>
     <Gender>M</Gender>
     <Age>32</Age>
  </Account>
  <Account>
     <CustomerID>1</CustomerID>
     <CustomerName>John Madsen</CustomerName>
     <ID>222</ID>
     <Name>BBB</Name>
     <Value>64</Value>
     <Gender>M</Gender>
     <Age>32</Age>
  </Account>
  <Account>
     <CustomerID>2</CustomerID>
     <CustomerName>Dona M. Graduate</CustomerName>
     <ID>333</ID>
     <Name>CCC</Name>
     <Value>5215</Value>
     <Gender>F</Gender>
     <Age>36</Age>
  </Account>
  <Account>
     <CustomerID>2</CustomerID>
     <CustomerName>Dona M. Graduate</CustomerName>
     <ID>555</ID>
     <Name>FFF</Name>
     <Value>6325</Value>
     <Gender>F</Gender>
     <Age>36</Age>
  </Account>

我正在使用以下XSL代码:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <Accounts>
        <xsl:for-each select="Customers/Customer/Accounts/Account">
            <Account>
                <xsl:apply-templates select="ancestor::Customer/*[not(*)]"/>
                <xsl:copy-of select="*" />

                <xsl:copy-of select="following::Profile/*"/>
            </Account>                
        </xsl:for-each>
    </Accounts>
</xsl:template>

<xsl:template match="Customer/*[not(*)]">
    <xsl:element name="{concat('Customer', name())}">
        <xsl:copy-of select="@*|node()"/>
    </xsl:element>
</xsl:template>

然而,我得到的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<Accounts>
  <Account>
     <CustomerID>1</CustomerID>
     <CustomerName>John Madsen</CustomerName>
     <ID>111</ID>
     <Name>AAA</Name>
     <Value>11234</Value>
     <Gender>M</Gender>
     <Age>32</Age>
     <Gender>F</Gender>
     <Age>36</Age>
  </Account>
  <Account>
     <CustomerID>1</CustomerID>
     <CustomerName>John Madsen</CustomerName>
     <ID>222</ID>
     <Name>BBB</Name>
     <Value>64</Value>
     <Gender>M</Gender>
     <Age>32</Age>
     <Gender>F</Gender>
     <Age>36</Age>
  </Account>
  <Account>
     <CustomerID>2</CustomerID>
     <CustomerName>Dona M. Graduate</CustomerName>
     <ID>333</ID>
     <Name>CCC</Name>
     <Value>5215</Value>
     <Gender>F</Gender>
     <Age>36</Age>
  </Account>
  <Account>
     <CustomerID>2</CustomerID>
     <CustomerName>Dona M. Graduate</CustomerName>
     <ID>555</ID>
     <Name>FFF</Name>
     <Value>6325</Value>
     <Gender>F</Gender>
     <Age>36</Age>
  </Account>

请注意,第一个节点有两个Gender和两个Age节点,接下来的关键字::不限制当前Customer节点中的后续节点,而是占用整个文档中的所有后续节点

所以我的问题是,如何限制以下:: keyword?或者是否有另一种方法将配置文件子节点复制到每个帐户节点?

由于 拉菲阿斯拉夫

1 个答案:

答案 0 :(得分:0)

您可以在父following-sibling::Profile元素上使用Accounts而不是过于宽泛 - 对于此特定案例选择器following::Profile

<xsl:copy-of select="../following-sibling::Profile/*"/>

<强> xsltransform.net demo

相关问题