【问题标题】:Selecting a node and its children from XML with XSLT使用 XSLT 从 XML 中选择一个节点及其子节点
【发布时间】:2014-08-13 11:14:37
【问题描述】:

我有一个 xml 文件,我需要选择(而不是删除)一个特定节点及其子节点。我知道如何删除一个及其子项,但不知道如何删除除这些之外的所有项。

输入的 xml 文件如下所示

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                     xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
         <wsse:UsernameToken wsu:Id="UsernameToken-8">
            <wsse:Username>john</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <seq:Request xmlns:seq="http://schemas.mycompany.com/schema_v1_0">
         <seq:StoreId>6</seq:StoreId>
         <seq:Concept>2</seq:Concept>
         <seq:ProductGr>
            <seq:ProductGroupID>10</seq:ProductGroupID>
            <seq:Seq>150</seq:Seq>
            <seq:Update>1</seq:Update>
         </seq:ProductGr>
      </seq:Request>
   </soapenv:Body>
</soapenv:Envelope>

我只想获得以下代码块

  <seq:Request xmlns:seq="http://schemas.mycompany.com/schema_v1_0">
     <seq:StoreId>6</seq:StoreId>
     <seq:Concept>2</seq:Concept>
     <seq:ProductGr>
        <seq:ProductGroupID>10</seq:ProductGroupID>
        <seq:Seq>150</seq:Seq>
        <seq:Update>1</seq:Update>
     </seq:ProductGr>
  </seq:Request>

你能帮帮我吗?此外,命名空间的前缀可以变化,尽管命名空间本身不会变化。

感谢您的帮助。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    最简单的方法是

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:template match="/">
        <xsl:copy-of select="soap:Envelope/soap:Body/*[1]"
                     xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" />
      </xsl:template>
    </xsl:stylesheet>
    

    这将提取Body 的第一个子元素,无论其名称如何。

    【讨论】:

    • 效果很好,但它会将命名空间 xmlns:soapenv 添加到所选节点,如下所示。 schemas.mycompany.com/schema_v1_0" xmlns:soapenv="schemas.xmlsoap.org/soap/envelope">
    • @ingenierocps 是正确的,因为该名称空间声明 在原始树中的该点生效。声明但不使用并没有任何害处。
    • @ingenierocps 如果您出于美学原因想要摆脱未使用的命名空间声明,您可以在 XSLT 2.0 中通过将 copy-namespaces="no" 添加到 copy-of 来实现,但在 XSLT 1.0 中您需要这样做使用模板复制而不是使用copy-of
    • 非常感谢。这真的很有帮助。我害怕命名空间。处理完这个 xml 后,我发送它,它必须针对 xsd 进行验证,我认为命名空间可能会弄乱这个验证,但根本不会。成功了!!!
    • 我没有看到你的最后评论。这就是蛋糕上的糖霜,它确实有效,而且现在没有命名空间。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 2020-02-17
    相关资源
    最近更新 更多