同じxmlファイル内の参照を置き換える必要があるという要件があります。制限は、xslt1.0のみを使用することです。
以下は私のサンプル入力xmlです。
<org>
<depts>
<dept>
<deptId>1009</deptId>
<deptName>IT</deptName>
<deptAccessCode>IT-1009</deptAccessCode>
</dept>
<dept>
<deptId>2344</deptId>
<deptName>BPO</deptName>
<deptAccessCode>BP-2344</deptAccessCode>
</dept>
</depts>
<employees>
<employee>
<name>abc</name>
<dept>
<REFERENCE>
<LocationXPath>/org/depts/dept[2]</LocationXPath>
</REFERENCE>
</dept>
<employee>
</employees>
</org>
ここで、ノードREFERENCEをXPath / org / depts /dept[2]の実際のデータに置き換えたいと思います。したがって、出力xmlは次のようになります。
<org>
<depts>
<dept>
<deptId>1009</deptId>
<deptName>IT</deptName>
<deptAccessCode>IT-1009</deptAccessCode>
</dept>
<dept>
<deptId>2344</deptId>
<deptName>BPO</deptName>
<deptAccessCode>BP-2344</deptAccessCode>
</dept>
</depts>
<employees>
<employee>
<name>abc</name>
<dept>
<deptId>2344</deptId>
<deptName>BPO</deptName>
<deptAccessCode>BP-2344</deptAccessCode>
</dept>
<employee>
</employees>
</org>
xmlツリー全体のさまざまなxpathを参照するさまざまな要素にいくつかのREFERENCEノードがあり、それらを実際のデータに置き換える必要があります。
<someWhereInTheXmlTree>
<sometag>
<REFERENCE>
<LocationXPath>some/reference[1]/to/a/node[3]/in/the[4]/same/xml</LocationXPath>
</REFERENCE>
</sometag>
<someWhereInTheXmlTree>
...
<ffff>
<bbbb>
<REFERENCE>
<LocationXPath>abc/xyz[1]/node[4]/element</LocationXPath>
</REFERENCE>
</bbbb>
<ffff>
これについて私を助けてください。助けてくれてありがとう。
これまで、参照を置き換えるために1つのXSLTを実装しましたが、不要な空の名前スペースに直面しています。
これが私のXSLTです
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tib="http://www.tibco.com/bw/xslt/custom-functions"
xmlns="http://www.realestate.org/residential/2010/schemas" >
<xsl:output omit-xml-declaration="no" indent="yes" method = "xml" />
<xsl:strip-space elements="*"/>
<xsl:param name="myxml" />
<xsl:template match="node()|@*">
<xsl:param name="isNodeToReplace"><xsl:call-template name="ReferenceCheck" /></xsl:param>
<xsl:choose>
<xsl:when test="$isNodeToReplace='true'">
<xsl:call-template name="replaceWithData">
<xsl:with-param name="ref"><xsl:value-of select="." /></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="ReferenceCheck">
<xsl:choose>
<xsl:when test="name(child::*[1])='REFERENCE' and name(child::*[1]//child::*[1])='LocationXPath'">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="replaceWithData">
<xsl:param name="ref" />
<xsl:copy-of select="tib:evaluate($myxml,$ref)" />
</xsl:template>
</xsl:stylesheet>
上記のXSLTでは、xml全体(処理中の同じxml)をパラメーター$myxmlとして渡します。
以下は私のサンプル入力XMLです-これはxmlのスニペットです、私が扱っている実際のxmlファイルは大きすぎて、非常に複雑なツリー構造を含んでいます。しかし、このサンプルxmlは私の問題を引き起こすのに十分です。
入力ファイル
<?xml version="1.0" encoding="UTF-8"?>
<org xmlns="http://www.realestate.org/residential/2010/schemas">
<depts>
<dept>
<deptId>1</deptId>
<deptName>health</deptName>
<deptAccessCode>HL007845</deptAccessCode>
</dept>
</depts>
<employees>
<employee>
<name>TOM</name>
<dept>
<REFERENCE>
<LocationXPath>/org/depts/dept[1]</LocationXPath>
</REFERENCE>
</dept>
</employee>
</employees>
</org>
私の出力ファイル
<?xml version="1.0" encoding="UTF-8"?>
<org xmlns="http://www.realestate.org/residential/2010/schemas">
<depts>
<dept>
<deptId>1</deptId>
<deptName>health</deptName>
<deptAccessCode>HL007845</deptAccessCode>
</dept>
</depts>
<employees>
<employee>
<name>TOM</name>
<dept xmlns="">
<deptId>1</deptId>
<deptName>health</deptName>
<deptAccessCode>HL007845</deptAccessCode>
</dept>
</employee>
</employees>
</org>
期待される出力
<?xml version="1.0" encoding="UTF-8"?>
<org xmlns="http://www.realestate.org/residential/2010/schemas">
<depts>
<dept>
<deptId>1</deptId>
<deptName>health</deptName>
<deptAccessCode>HL007845</deptAccessCode>
</dept>
</depts>
<employees>
<employee>
<name>TOM</name>
<dept>
<deptId>1</deptId>
<deptName>health</deptName>
<deptAccessCode>HL007845</deptAccessCode>
</dept>
</employee>
</employees>
</org>
そのため、置き換えられたルート要素の<< dept xmlns="">>に不要な空の名前空間が表示されます。これが私の問題を明確に説明できることを願っています
最終的に私は、不要な空の名前スペースを削除するための解決策を以下のリンクで見つけました。 http://social.msdn.microsoft.com/forums/en-US/xmlandnetfx/thread/0de59291-ef3a-4a4c-9ca5-17923b16a504
これが新しいXSLTです
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tib="http://www.tibco.com/bw/xslt/custom-functions"
xmlns="http://www.realestate.org/residential/2010/schemas" >
<xsl:output omit-xml-declaration="no" indent="yes" method = "xml" />
<xsl:strip-space elements="*"/>
<xsl:param name="myxml" />
<xsl:template match="node()|@*">
<xsl:param name="isNodeToReplace"><xsl:call-template name="ReferenceCheck" /></xsl:param>
<xsl:choose>
<xsl:when test="$isNodeToReplace='true'">
<xsl:call-template name="replaceWithData">
<xsl:with-param name="ref"><xsl:value-of select="." /></xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="ReferenceCheck">
<xsl:choose>
<xsl:when test="name(child::*[1])='REFERENCE' and name(child::*[1]//child::*[1])='LocationXPath'">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="replaceWithData">
<xsl:param name="ref" />
<xsl:apply-templates select="tib:evaluate($myxml,$ref)" mode="move-to-namespace">
<xsl:with-param name="namespace" select="'http://www.realestate.org/residential/2010/schemas'" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*" mode="move-to-namespace">
<xsl:param name="namespace" />
<xsl:element name="{local-name()}" namespace="{$namespace}">
<xsl:copy-of select="@*" />
<xsl:apply-templates select="node()" mode="move-to-namespace">
<xsl:with-param name="namespace" select="$namespace"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<xsl:template match="text() | comment() | processing-instruction()" mode="move-to-namespace">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
xsltの専門家がそれをさらに改良して、適切な説明を伴う不要な指示を回避する場合は、非常にうれしいです。
前もって感謝します