[英]XML - XSLT - Using two XML input documents
我有一個可能很容易解決的小問題,但是我整個下午都在忙着解決,我真的不知道該如何解決,
基本上,我有以下輸入XML文檔:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<childs>
<child ID="1" name="John" />
<child ID="2" name="Marie"/>
<child ID="3" name="Joseph"/>
</childs>
</parent>
而且我想向其中添加另一個<child>
元素,但是我想從一個名為“ inputStack.xml”的外部文件中獲得該孩子的名字:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design">
<property name="units">in</property>
<text-property name="displayName">Daisy</text-property>
<text-property name="text">Just plain text</text-property>
</report>
基本上,我想添加一個名為Daisy的新<child>
元素
所以這是我想要獲得的輸出XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<childs>
<child ID="1" name="John"/>
<child ID="2" name="Marie"/>
<child ID="3" name="Joseph"/>
<child ID="4" name="Daisy"/>
</childs>
</parent>
這是我正在使用的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
expand-text="yes"
version="3.0">
<xsl:output indent="yes" />
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="parent/childs/child[last()]">
<xsl:next-match/>
<child>
<xsl:attribute name="ID">
<xsl:value-of select="count(preceding-sibling::child)+2" />
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="document('inputStack.xml')/report/text-property[@name = 'displayName']"/>
</xsl:attribute>
</child>
</xsl:template>
</xsl:stylesheet>
我得到的輸出是這樣的:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<childs>
<child ID="1" name="John"/>
<child ID="2" name="Marie"/>
<child ID="3" name="Joseph"/>
<child ID="4" name=""/>
</childs>
</parent>
如您所見,我無法獲得屬性name
值等於displayName
的text-property
元素中的值...
現在這是我的問題所在:如您所見,我正在使用的外部文件/文檔具有xmlns
屬性,其值為http://www.eclipse.org/birt/2005/design
。 我發現,如果刪除此屬性,則XSLT代碼將起作用,並將值Daisy
添加到生成的XML文檔中。 但是問題是我無法從外部XML文件中刪除該屬性,那么如何為該外部文檔定義一個名稱空間以使其起作用? 還是有其他方法可以做到這一點?
謝謝!
編輯/更新
我正在嘗試在count()
函數中使用document()
函數,但我不知道為什么它不起作用...因此我正在使用的外部文件已更新:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design">
<property name="units">in</property>
<text-property name="displayName">Daisy</text-property>
<text-property name="text">Just plain text</text-property>
<propList>
<prop name="prop1"/>
<prop name="prop2"/>
<prop name="prop3"/>
<prop name="prop4"/>
<prop name="prop5"/>
</propList>
</report>
這是我的XSLT更新:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ecd="http://www.eclipse.org/birt/2005/design"
exclude-result-prefixes="xs ecd"
expand-text="yes"
version="3.0">
<xsl:output indent="yes" />
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="parent/childs/child[last()]">
<xsl:next-match/>
<child>
<xsl:attribute name="ID">
<xsl:value-of select="count(preceding-sibling::child)+2" />
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="document('inputStack.xml')/ecd:report/ecd:text-property[@name = 'displayName']"/>
</xsl:attribute>
<!--new attribute-->
<xsl:attribute name="nProps">
<xsl:value-of select="count(document('inputStack.xml')/ecd:report/ecd:propList/(preceding-sibling::ecd:prop[last()]))+1"/>
</xsl:attribute>
</child>
</xsl:template>
</xsl:stylesheet>
這是我得到的結果:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<childs>
<child ID="1" name="John"/>
<child ID="2" name="Marie"/>
<child ID="3" name="Joseph"/>
<child ID="4" name="Daisy" nProps="1"/>
</childs>
</parent>
所以nProps
值應該是5而不是1 ...我在路徑中做錯了嗎? 謝謝
亞歷山大·雅辛托(Alexandre Jacinto)
對於該單一指令,您可以使用
<xsl:value-of xpath-default-namespace="http://www.eclipse.org/birt/2005/design" select="document('inputStack.xml')/report/text-property[@name = 'displayName']"/>
參見https://www.w3.org/TR/xslt-30/#unprefixed-qnames 。 如果在需要使用名稱空間的地方還有更多XSLT元素,則可以在通用容器元素上聲明xpath-default-namespace
,但是請記住,您要使用具有不同名稱空間的兩個文檔,因此需要確保使用這些元素如果您需要默認名稱空間為空,則不要覆蓋它。
根據您的需求,在樣式表中使用<xsl:stylesheet xmlns:ecd="http://www.eclipse.org/birt/2005/design" ...>
聲明名稱空間的前綴可能更容易,並且使用該前綴,然后在需要的位置限定XPath表達式中的元素名稱document('inputStack.xml')/ecd:report/ecd:text-property[@name = 'displayName']
。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs mn" xmlns:mn="http://www.eclipse.org/birt/2005/design"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="doc" select="document('date3.xml')"/>
<xsl:template match="parent">
<xsl:copy>
<childs>
<xsl:for-each select="childs/child">
<child>
<xsl:attribute name="ID">
<xsl:value-of select="@ID"/>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
</child>
</xsl:for-each>
<child>
<xsl:attribute name="ID">
<xsl:value-of select="'4'"/>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="$doc/mn:report/mn:text-property[@name='displayName']"/>
</xsl:attribute>
</child>
</childs>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.