【问题标题】:XSLT - Extract some Elements with subnodes (.net XSLT 1.0)XSLT - 提取一些带有子节点的元素 (.net XSLT 1.0)
【发布时间】:2015-04-08 13:14:40
【问题描述】:

我在从 XML 文档中仅提取几个节点时遇到了一些麻烦。 在我的情况下,我只得到我的子节点的“值”,而不是节点及其子节点本身。 我使用 .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”及其子节点(稍后还有其他一些节点)-但我想保留结构。

我的 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#代码的sn-p:

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. 您向我们展示的结果不是应用您的代码时收到的结果。 2. 正如我在your previous question 中向您解释的那样,如果不复制元素的命名空间,您就无法复制元素。
  • 这个问题不是我的问题 - 但谢谢你指点我那篇文章..我看看它
  • 糟糕,抱歉。关于那个。
  • @Cadburry 在样式表中,将http://www.k-5.at/publicservices/download/MassenDatenResponseHaushalt:001 作为默认命名空间是没有用的——这个默认值仅适用于 XSLT 文档中的元素,不适用于其中的 XPath 表达式。使用 prefix 声明此名称空间 - 并为 XSLT 样式表中提到的输入文档中的所有元素添加前缀。 (这仍然不能解决输入元素具有命名空间的问题,但它应该消除一些关于查找它们的困惑。)
  • @MathiasMüller Thx - 这帮助了我 - 我将声明从:xmlns="k-5.at/publicservices/download/MassenDatenResponseHaushalt:001" 更改为:xmlns:xxx="k-5.at/publicservices/download/MassenDatenResponseHaushalt:001" 并使用 xxx 作为前缀 - 现在它可以工作了- 谢谢你们俩

标签: c# .net xml xslt xpath


【解决方案1】:
  1. 您向我们展示的结果不是应用您的代码时收到的结果。

  2. 如果你删除第 11 行,你会得到你想要的结果:

    &lt;xsl:apply-templates/&gt;

当你这样做时,你可以将整个事情简化为:

<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>

编辑

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

如 cmets 中所述,如果不复制元素的命名空间,则无法复制元素。如果您希望输出不在命名空间中,则需要为每个“旧”元素创建一个新元素。在对源文档中的元素进行寻址时,您还必须使用前缀:

<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>

【讨论】:

  • @Cadburry 仍然不是运行代码时得到的结果。
  • @Cadburry:您问题中的任何代码或源代码都无法解释名为MassenDatenResponse 的节点的存在。
  • @Flynn1179 - 现在结果是正确的(替换了本地化的名称) - 我知道一件主要的事情(sry) - 命名空间......! (也更正了) - 看起来这是没有 ns 解决方案的主要问题......你能给我一个提示吗?
  • iv 在您的编辑中使用了该解决方案 - 我不希望输出中的命名空间 - thx
猜你喜欢
  • 2021-02-02
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多