XSLT - 使用子节点(.net XSLT 1.0)提取一些元素

时间:2015-04-08 13:14:41

标签: c# .net xml xslt xpath

我有一些小问题只能从XML-Document中提取几个节点。 在我的情况下,我只获得我的子节点的“价值”,而不是节点及其子节点本身。 我使用.net 3.5 c#来转换文档(XslCompiledTransform.Transform)。

示例XML(来源)

<?xml version="1.0" encoding="utf-8"?>
<Response xmlns="http://www.k-5.at/publicservices/download/MassenDatenResponseHaushalt:001"> 
    <Header>
        <PaketType>Household</PaketType>
        <ClientUid>6d513eae-b17f-4c30-b1eb-036ef36c5e8c</ClientUid>
        <ClientName>DEMO</ClientName>
        <UserLoginName>DEMO1</UserLoginName>
        <UserDisplayName>Demo1 User</UserDisplayName>
        <PointOfTime>2015-02-19T10:37:11.0768481+01:00</PointOfTime>
    </Header>
    <HeaderHousehold>
        <CustomerNumber>70716</CustomerNumber>
    </HeaderHousehold>
    <DataHouseHold>
        <Years>
            <YearData>
                <Year>2015</Year>
            </YearData>    
        </Years>
    </DataHouseHold>
    <DataDebts>
        <Years>
            <YearData>
                <Year>2015</Year>
            </YearData>
        </Years>
    </DataDebts>
</Response>

我想要实现的是选择“Repsonse / Header-Node”&amp;它的输出子节点(后来也是其他节点) - 但我想保留结构。

我的xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns="http://www.k-5.at/publicservices/download/MassenDatenResponseHaushalt:001"               
                    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <xsl:element name= "Response">
            <xsl:element name= "Header">
                <xsl:copy-of select = "/Response/Header/node()"/>        
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

我得到的结果: (我只将“Header”节点作为值...)

<Response>
    <Header>Household6d513eae-b17f-4c30-b1eb-036ef36c5e8cDEMORDEMO1Demo1 User2015-02-19T10:37:11.0768481+01:007071620152015</Header>
</Response>

结果如何:

<Response> 
    <Header>
        <PaketType>Household</PaketType>
        <ClientUid>6d513eae-b17f-4c30-b1eb-036ef36c5e8c</ClientUid>
        <ClientName>DEMO</ClientName>
        <UserLoginName>DEMO1</UserLoginName>
        <UserDisplayName>Demo1 User</UserDisplayName>
        <PointOfTime>2015-02-19T10:37:11.0768481+01:00</PointOfTime>
    </Header>
</Response> 

我希望有人可以帮助我。

非常感谢!

修改

我的c#代码片段:

XPathDocument myXPathDoc = new XPathDocument(xml);
                XslCompiledTransform myXslTrans = new XslCompiledTransform();

                myXslTrans.Load(xslt);

                if (System.IO.File.Exists("result.xml"))
                    System.IO.File.Delete("result.xml");

                XmlTextWriter myWriter = new XmlTextWriter("result.xml", null);
                myWriter.Formatting = Formatting.Indented;
                myXslTrans.Transform(myXPathDoc, null, myWriter);

                myWriter.Close();

1 个答案:

答案 0 :(得分:1)

  1. 您向我们展示的结果是应用您的代码时收到的结果。

  2. 如果删除第11行,您将获得您正在寻找的结果:

    <xsl:apply-templates/>

  3. 虽然您正在使用它,但您可以将整个过程简化为:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">               
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/Response">
        <Response>
            <xsl:copy-of select="Header"/>        
        </Response>
    </xsl:template>
    
    </xsl:stylesheet>
    

    修改

    响应您编辑的输入,将整个响应放在命名空间中:

    如评论中所述,您无法在不复制其名称空间的情况下复制元素。如果您希望输出不在命名空间中,则需要为每个&#34; old&#34;创建一个新元素。一。在处理源文档中的元素时,您还必须使用前缀:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:k5="http://www.k-5.at/publicservices/download/MassenDatenResponseHaushalt:001"
    exclude-result-prefixes="k5">               
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/k5:Response">
        <Response>
            <xsl:apply-templates select="k5:Header"/>        
        </Response>
    </xsl:template>
    
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates/>        
        </xsl:element>
    </xsl:template>
    
    </xsl:stylesheet>