gpt4 book ai didi

当输入 XML 具有命名空间时,XSLT2.0 给出空输出

转载 作者:行者123 更新时间:2023-12-04 16:51:28 24 4
gpt4 key购买 nike

要求是在 XML 中找到重复元素(BaseName)并使用 isDuplicate 属性标记父元素(Account)。当输入 XML RootElement 没有命名空间时,XSL 工作正常。当根元素有命名空间时,我得到空对象。我不确定为什么命名空间会导致 XSL 生成空输出。任何获得正确输出的帮助将不胜感激。`

输入带有命名空间的 XML

 <?xml version="1.0"?>
<objects xmlns="urn:s.sexmaple.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Account>
<Id>001A00F</Id>
<RecordTypeId>012A00</RecordTypeId>
<BaseName>EFGH</BaseName>
</Account>
<Account>
<Id>001A0</Id>
<RecordTypeId>012A0</RecordTypeId>
<BaseName>ABCD</BaseName>
</Account>
<Account>
<Id>001A</Id>
<RecordTypeId>012A</RecordTypeId>
<BaseName>ABCD</BaseName>
</Account>
</objects>

XSL
    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml"
version="1.0"
encoding="UTF-8"
indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="Accounts">
<objects>
<xsl:for-each select="//Account">
<xsl:sort select="BaseName" />
<xsl:apply-templates select="." />
</xsl:for-each>
</objects>
</xsl:variable>
<xsl:variable name="unqentity">
<objects>
<xsl:for-each select="$Accounts/objects/Account">
<xsl:choose>
<xsl:when test="not(following-sibling::Account/BaseName=./BaseName) and not(preceding-sibling::Account/BaseName=./BaseName) ">
<xsl:copy-of select="." />
</xsl:when>
<xsl:otherwise>
<Account>
<xsl:attribute name="isDuplicate">yes</xsl:attribute>
<xsl:for-each select="child::*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*|node()" />
</xsl:element>
</xsl:for-each>
</Account>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</objects>
</xsl:variable>
<xsl:copy-of select="$unqentity" />
</xsl:template>
</xsl:stylesheet>

输入 XML 具有命名空间时输出 XML
 <?xml version="1.0" encoding="UTF-8"?>
<objects/>

当输入没有命名空间时输出 XML
<?xml version="1.0" encoding="UTF-8"?>
<objects>
<Account>
<Id>001A00F</Id>
<RecordTypeId>012A00</RecordTypeId>
<BaseName>EFGH</BaseName>
</Account>
<Account isDuplicate="yes">
<Id>001A0</Id>
<RecordTypeId>012A0</RecordTypeId>
<BaseName>ABCD</BaseName>
</Account>
<Account isDuplicate="yes">
<Id>001A</Id>
<RecordTypeId>012A</RecordTypeId>
<BaseName>ABCD</BaseName>
</Account>
</objects>

最佳答案

当您有命名空间时,这意味着命名空间中的元素与没有命名空间的元素(或者实际上是不同命名空间中的元素)不同。

这意味着当您在 XSLT 中执行此操作时...

 <xsl:for-each select="//Account">

您正在寻找一个 帐号没有命名空间的元素,因此它不会匹配 帐号源 XML 中的元素,该元素位于标题有趣的“urn:s.sexmaple.com”(我怀疑是拼写错误)

但是,当您使用 XSLT2.0 时,有一种简单的方法可以解决此问题,即使用 为任何 xpath 表达式指定默认 namespace 。 xpath-default-namespace .通常,这可能就足够了,但是通过在变量中创建新元素来使问题稍微复杂一些,然后您可以尝试选择这些元素。
<xsl:for-each select="$Accounts/objects/Account">

这意味着当您创建 时对象 帐号 中的元素$账户变量,它们也需要成为命名空间的一部分。

切入正题,这就是您的 xsl:样式表元素需要看起来像
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
xmlns="urn:s.sexmaple.com"
xpath-default-namespace="urn:s.sexmaple.com">

所以, xpath-default-namespace="urn:s.sexmaple.com"用于匹配源 XML 中的元素,而 xmlns="urn:s.sexmaple.com"用于确保您在变量中创建的元素具有此命名空间,并且可以稍后进行匹配。

说了这么多,您已经使整个 XSLT 过于复杂了。您是否只是想添加 IsDuplicate 归因于 帐号相同的元素 基本名称 ?好吧,创建一个键来查找重复项,就像这样
<xsl:key name="account" match="Account" use="BaseName" />

然后你可以像这样查找重复项:
         <xsl:if test="key('account', BaseName)[2]">
<xsl:attribute name="isDuplicate">Yes</xsl:attribute>
</xsl:if>

试试这个 XSLT,它应该给出相同的结果
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="urn:s.sexmaple.com">
<xsl:output method="xml" indent="yes"/>

<xsl:key name="account" match="Account" use="BaseName" />

<xsl:template match="Account">
<xsl:copy>
<xsl:if test="key('account', BaseName)[2]">
<xsl:attribute name="isDuplicate">Yes</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

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

注意这如何只需要使用 xpath-default-namespace因为它不是创建全新的元素,只是复制现有元素(也复制了它们的命名空间)。

关于当输入 XML 具有命名空间时,XSLT2.0 给出空输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19940262/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com