簡體   English   中英

XML-XSLT-使用兩個XML輸入文檔

[英]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值等於displayNametext-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM