XML到XML转换使用不同的内部节点但使用XSLT具有相同的外部节点

时间:2016-05-09 07:11:22

标签: xml xslt

我已经开始学习XSLT

当我正在处理时,我得到了错误的XML格式     输入

<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
  <test>
    <access1>113AL</access1>
    <access2>119AL</access2>
  </test>
  <test>
    <access2>115AL</access2>
    <access3>116AL</access3>
  </test>
  <test>
    <access4>118AL</access4>
    <access5>119AL</access5>
  </test>
  <copies>
    <test2>
      <a>113AL</a>
      <Copy1>Y</Copy1>
    </test2>
    <test2>
      <a>113AX</a>
      <Copy1>N</Copy1>
    </test2>
  </copies>
</root>

预期产出

<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
  <test>
    <access1>113AL</access1>
    <Indicator>true</Indicator>
    <Copy>Y</Copy>
    <access2>119AL</access2>
  </test>
  <test>
    <access2>115AL</access2>
    <access3>116AL</access3>
  </test>
  <test>
    <access4>118AL</access4>
    <access5>119AL</access5>
  </test>
</root>

我试图将root / test / access值与root / test / access进行比较。如果找到匹配项,则应包含相应的复制标记。 我的XSL

<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<xsl:for-each select="test">
<test>
<access1><xsl:value-of select="//access1"/></access1>
<access2><xsl:value-of select="//access2"/></access2>
<xsl:for-each select="root/copies/test2/access">
<xsl:if test ="access1=test2/access">
<Copy>Y</Copy>
</xsl:if>
</xsl:for-each>
</test>
</xsl:for-each>
<xsl:for-each select="test">
<test>
<access2><xsl:value-of select="//access2"/></access2>
<access3><xsl:value-of select="//access3"/></access3>
<xsl:for-each select="root/copies/test2/access">
<xsl:if test ="access1=test2/access">
<Copy>Y</Copy>
</xsl:if>
</xsl:for-each>
</test>
</xsl:for-each>
<xsl:for-each select="test">
<test>
<access4><xsl:value-of select="//access4"/></access4>
<access5><xsl:value-of select="//access5"/></access5>
<xsl:for-each select="root/copies/test2/access">
<xsl:if test ="access1=test2/access">
<Copy>Y</Copy>
</xsl:if>
</xsl:for-each>
</test>
</xsl:for-each>
</root>

这给了我错误的输出。任何人都可以在这里帮助我,我犯了一个错误,请帮助我在XSLT 1.0中如何做到这一点?

2 个答案:

答案 0 :(得分:0)

你的XSLT转换文件看起来很奇怪,看看教程以便更好地了解XSLT的工作原理,对于eaxmple:http://www.w3schools.com/xsl/default.asp

对于您的情况,我建议您使用以下XSLT:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <xsl:element name="root">
        <xsl:apply-templates name="copyTest" />
    </xsl:element>
</xsl:template>

<xsl:template name="copyTest" match="root">
    <xsl:copy-of select="test"></xsl:copy-of>
</xsl:template>

test元素直接复制到元素root下,但不复制元素Copies下的元素

答案 1 :(得分:0)

整个问题有点令人困惑 输入xml 仍然不是valide:我使用这个固定版本:

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
        <test>
            <access1>113AL</access1>
            <access2>119AL</access2>
        </test>
        <test>
            <access2>115AL</access2>
            <access3>116AL</access3>
        </test>
        <test>
            <access4>118AL</access4>
            <access5>119AL</access5>
        </test>
        <copies>
            <test2>
                <access>113AL</access>
                <Copy>Y</Copy>
            </test2>
            <test2>
                <access>113AX</access>
                <Copy>N</Copy>
            </test2>
            </copies>
    </root>

另外

  

我试图将root / test / access值与root / test / access进行比较。如果找到匹配项,则应包含相应的复制标记。

似乎应该将root / test / access值与 root / copies / test2 / access

进行比较

因此您可以尝试:

<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="test">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:variable name="thisaccess" select="*[starts-with(name(), 'access')]" />
            <xsl:apply-templates select="//copies/test2[access=$thisaccess]/Copy" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="copies"/>

</xsl:stylesheet>

使用以下输出:

        <root>
            <test>
                <access1>113AL</access1>
                <access2>119AL</access2>
                <Copy>Y</Copy>
            </test>
            <test>
                <access2>115AL</access2>
                <access3>116AL</access3>
            </test>
            <test>
                <access4>118AL</access4>
                <access5>119AL</access5>
            </test>
        </root>

更新:由于评论。

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="test/*[starts-with(name(), 'access')]">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
    <xsl:variable name="thisaccess" select="." />
    <xsl:apply-templates select="//copies/test2[access=$thisaccess]/Copy" />
</xsl:template>

<xsl:template match="copies"/>

新输出:

<root>
    <test>
        <access1>113AL</access1>
        <Copy>Y</Copy>
        <access2>119AL</access2>
    </test>
    <test>
        <access2>115AL</access2>
        <access3>116AL</access3>
    </test>
    <test>
        <access4>118AL</access4>
        <access5>119AL</access5>
    </test>
 </root>