如何使用 xslt 从文档方法中删除节点

发布于 2025-01-07 18:42:39 字数 3100 浏览 0 评论 0原文

下面是 document_1.xml

<products>
    <product>
        <name>Pen</name>
        <Quantity>10</Quantity>
    </product>
    <product>
        <name>Pencil</name>
        <Quantity>20</Quantity>
    </product>
    <product>
        <name>Bag</name>
        <Quantity>25</Quantity>
    </product>
</products>

document_2.xml

<products>
    <product>
        <name>Pen</name>
        <Quantity>30</Quantity>
    </product> 

    <product>
        <name>Pencil</name>
        <Quantity>5</Quantity>
    </product>
    <product>
        <name>Bag</name>
        <Quantity>2</Quantity>
    </product>
</products>

以及 document.xml

<products>
</products>

下面是我的 xsl,我曾经加入 document_1 .xmldocument_2.xmldocument.xml

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="ns">
<xsl:output method="xml" indent="yes"/>

<xsl:key name="kProdByName" match="product" use="name"/>

<xsl:template match="products">
<xsl:copy>

<xsl:variable name="msNodes">
    <xsl:apply-templates select="document('document_1.xml')/*/product|document('document_2.xml')/*/product">
    <xsl:sort select="Quantity" data-type="number"/>
    </xsl:apply-templates> 
</xsl:variable>

<xsl:apply-templates select="ns:node-set($msNodes)/product [generate-id() =  generate-id(key('kProdByName', name)[1])  ]"/>

</xsl:copy>
</xsl:template>


<xsl:template match="product">
   <product>
    <xsl:for-each select="key('kProdByName', name)">
      <xsl:if test="position() = 1">
        <xsl:copy-of select="node()"/>
      </xsl:if>
    </xsl:for-each>
   </product>
</xsl:template>

</xsl:stylesheet>

以上 xsl 的输出在

<products>
    <product>
        <name>Bag</name>
        <Quantity>2</Quantity>
    </product>
    <product>
        <name>Pencil</name>
        <Quantity>5</Quantity>
    </product>
    <product>
        <name>Pen</name>
        <Quantity>10</Quantity>
    </product>
    </product>

这里,我需要删除 > 使用输出中的节点xslt 1.0

我需要如下输出

<products>
    <product>
        <name>Bag</name>
    </product>
    <product>
        <name>Pencil</name>
    </product>
    <product>
        <name>Pen</name>
    </product>
    </product> 

below is the document_1.xml

<products>
    <product>
        <name>Pen</name>
        <Quantity>10</Quantity>
    </product>
    <product>
        <name>Pencil</name>
        <Quantity>20</Quantity>
    </product>
    <product>
        <name>Bag</name>
        <Quantity>25</Quantity>
    </product>
</products>

and document_2.xml is

<products>
    <product>
        <name>Pen</name>
        <Quantity>30</Quantity>
    </product> 

    <product>
        <name>Pencil</name>
        <Quantity>5</Quantity>
    </product>
    <product>
        <name>Bag</name>
        <Quantity>2</Quantity>
    </product>
</products>

and document.xml is

<products>
</products>

Below is my xsl, i used to join document_1.xml and document_2.xml to the document.xml

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="ns">
<xsl:output method="xml" indent="yes"/>

<xsl:key name="kProdByName" match="product" use="name"/>

<xsl:template match="products">
<xsl:copy>

<xsl:variable name="msNodes">
    <xsl:apply-templates select="document('document_1.xml')/*/product|document('document_2.xml')/*/product">
    <xsl:sort select="Quantity" data-type="number"/>
    </xsl:apply-templates> 
</xsl:variable>

<xsl:apply-templates select="ns:node-set($msNodes)/product [generate-id() =  generate-id(key('kProdByName', name)[1])  ]"/>

</xsl:copy>
</xsl:template>


<xsl:template match="product">
   <product>
    <xsl:for-each select="key('kProdByName', name)">
      <xsl:if test="position() = 1">
        <xsl:copy-of select="node()"/>
      </xsl:if>
    </xsl:for-each>
   </product>
</xsl:template>

</xsl:stylesheet>

The output of above xsl is

<products>
    <product>
        <name>Bag</name>
        <Quantity>2</Quantity>
    </product>
    <product>
        <name>Pencil</name>
        <Quantity>5</Quantity>
    </product>
    <product>
        <name>Pen</name>
        <Quantity>10</Quantity>
    </product>
    </product>

here i need to remove <Quantity> node from the output using xslt 1.0

i need output like below

<products>
    <product>
        <name>Bag</name>
    </product>
    <product>
        <name>Pencil</name>
    </product>
    <product>
        <name>Pen</name>
    </product>
    </product> 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

歌入人心 2025-01-14 18:42:39

匹配 Quantity 的空模板应该可以做到这一点:

<xsl:template match="Quantity"/>

An empty template matching Quantity should do it:

<xsl:template match="Quantity"/>
就像说晚安 2025-01-14 18:42:39

替换

<xsl:copy-of select="node()"/>

<xsl:copy-of select="node()[not(self::Quantity)]"/>

或者,如果 Quantity 不是 product 的直接子级,而是后代,则将上面的内容替换为:

<xsl:apply-templates mode="skipQuantity"/>

并添加以下模板:

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

<xsl:template match="Quantity" mode="skipQuantity"/>

注意

虽然这些更改产生了新的想要的结果,但许多先前的处理变得不必要,可以完全省略。

转换可以大大简化为(没有找到最小数量,只是根据产品名称进行分组):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="ns">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="kProdByName" match="product" use="name"/>

    <xsl:template match="products">
        <xsl:copy>
            <xsl:variable name="msNodes">
                    <xsl:copy-of select=
                    "document('document_1.xml')/*/product
                |
                     document('document_2.xml')/*/product"/>
            </xsl:variable>

            <xsl:apply-templates select=
             "ns:node-set($msNodes)/product
                  [generate-id()
                  =
                   generate-id(key('kProdByName', name)[1])
                   ]"/>
        </xsl:copy>
    </xsl:template>

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

 <xsl:template match="Quantity"/>
</xsl:stylesheet>

Replace:

<xsl:copy-of select="node()"/>

with:

<xsl:copy-of select="node()[not(self::Quantity)]"/>

Or, if Quantity isn't a direct child of product, but a descendant, then replace the above with:

<xsl:apply-templates mode="skipQuantity"/>

and also add the following templates:

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

<xsl:template match="Quantity" mode="skipQuantity"/>

Do notice:

While these changes produce the new wanted result, a lot of the previous processing becomes unnecessary and can be omitted completely.

The transformation can be simplified significantly to this (no finding of minimum quantity, just grouping based on product name):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="ns">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="kProdByName" match="product" use="name"/>

    <xsl:template match="products">
        <xsl:copy>
            <xsl:variable name="msNodes">
                    <xsl:copy-of select=
                    "document('document_1.xml')/*/product
                |
                     document('document_2.xml')/*/product"/>
            </xsl:variable>

            <xsl:apply-templates select=
             "ns:node-set($msNodes)/product
                  [generate-id()
                  =
                   generate-id(key('kProdByName', name)[1])
                   ]"/>
        </xsl:copy>
    </xsl:template>

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

 <xsl:template match="Quantity"/>
</xsl:stylesheet>
薄荷港 2025-01-14 18:42:39

尝试添加

<xsl:template match="/products/product/Quantity"/>

Try adding

<xsl:template match="/products/product/Quantity"/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文