2

要件は、XML で重複する要素 (BaseName) を見つけ、親要素 (Account) を isDuplicate 属性でマークすることです。入力 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>
4

2 に答える 2

0

名前空間のない入力 XML が機能する理由は、名前空間のある XML が機能しない理由であり、入力 XML が原因ではなく、XSLT スタイルシートが原因です。

XML ファイルにデフォルトの名前空間がある場合、その名前空間をスタイルシート自体で宣言する必要があります。

たとえば、次の XML を使用します。

<test xmlns="test.xml.schema">
  <element>Content</element>
</test>

次の XSLT を適用すると:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:template match="/">
    <out>
       <namespace>None</namespace>
       <xsl:apply-templates />
    </out>
  </xsl:template>

  <xsl:template match="test">
    <test out="True">hello</test>
  </xsl:template>
  <xsl:template match="*"/>

</xsl:stylesheet>

出力は次のとおりです。

<out><namespace>None</namespace></out>

名前空間のないスタイルシートでの一致は実際に<xsl:template match="test">は. したがって、一致することはありません。test.xml.schema:test:test

ただし、入力ドキュメントの名前空間を追加してテンプレートを変更するだけの場合は、次のようになります。

<xsl:stylesheet xmlns:t="test.xml.schema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:template match="/">
    <out>
       <namespace>test.xml.schema</namespace>
       <xsl:apply-templates />
    </out>
  </xsl:template>

  <xsl:template match="t:test">
    <test out="True">hello</test>
  </xsl:template>
  <xsl:template match="*"/>

</xsl:stylesheet>    

出力は次のようになります。

<out xmlns:t="test.xml.schema">
  <namespace>test.xml.schema</namespace>
  <test out="True">hello</test>
</out>

入力ドキュメントと XSL の名前空間の省略形は同じである必要はありませんが (たとえば、空白と " t")、名前空間自体は同じであることに注意することが重要です (たとえば、空白と " t"の両方を にバインドする必要test.xml.schemaがあります) 。 .

また、XSLT でデフォルトの名前空間を使用すると、問題が発生する可能性があることに注意してください。したがって、XSLT で宣言された名前空間を使用するのが最善です。

于 2013-11-12T22:38:41.430 に答える