解析 XML 文件以获取所有 Namespace 信息 [英] Parse XML file to get all Namespace information

查看:28
本文介绍了解析 XML 文件以获取所有 Namespace 信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够从给定的 XML 文件中获取所有命名空间信息.

I want to be able to get all namespace information from a given XML File.

例如,如果输入的 XML 文件类似于:

So for example, if the input XML File is something like:

<ns1:create xmlns:ns1="http://predic8.com/wsdl/material/ArticleService/1/">
   <ns1:article xmlns:ns1="xmlns:ns1='http://predic8.com/material/1/">
      <ns1:id>1</ns1:id>
      <description>bar</description>
      <name>foo</name>
      <ns1:price>
         <amount>00.00</amount>
         <currency>USD</currency>
      </ns1:price>
      <ns1:price>
         <amount>11.11</amount>
         <currency>AUD</currency>
      </ns1:price>
   </ns1:article>
   <ns1:article xmlns:ns1="xmlns:ns1='http://predic8.com/material/1/">
      <ns1:id>2</ns1:id>
      <description>some name</description>
      <name>some description</name>
      <ns1:price>
         <amount>00.01</amount>
         <currency>USD</currency>
      </ns1:price>
   </ns1:article>
</ns1:create>

我希望输出看起来像这样(在这种情况下以逗号分隔):

I would like to expect an output that looks something like this (in this case comma-separated):

create, ns1, http://predic8.com/wsdl/material/ArticleService/1/
article, ns1, http://predic8.com/material/1/
price, ns1, http://predic8.com/material/1/
id, ns1, http://predic8.com/material/1/

重要说明:

重要的是,我们还要考虑在特定命名空间内定义的子节点,但其定义可能在更高的节点上定义.比如我们还是想取节点ns1:id,这里需要回溯到父节点ns1:article,发现namespace url是xmlns:ns1='http://predic8.com/material/1/

It is important that we also consider sub-nodes which are defined within a specific namespace, but whose definition may be defined at a higher node. For example, we would still like to pick up the node ns1:id, where we need to trace back to the parent node ns1:article to discover that the namespace url is xmlns:ns1='http://predic8.com/material/1/

我是用 Java 实现的,所以我不介意基于 Java 的解决方案,甚至基于 XSLT 的解决方案可能看起来合适.

I am implementing in Java, so I would not mind either a Java-based solution, or even a XSLT-based solution might seem appropriate.

推荐答案

进一步开发了 Michael Kay 提出的 XPath 表达式(实际上是一种简化)来处理属于默认命名空间:

Further developed the XPath expression proposed by Michael Kay (seems actually as a simplification) to also process unprefixed element names that belong to a default namespace:

distinct-values(//*[namespace-uri()]
                    /concat(local-name(),
                            ', ',
                            substring-before(name(), ':'),
                            ', ',
                            namespace-uri(),
                            '&#xA;'
                            )
                )

在以下文档上计算此 XPath 表达式时(提供的文档,但添加了位于默认命名空间中的元素):

When this XPath expression is evaluated on the following document (the provided one but with an added element that is in a default namespace):

<ns1:create xmlns:ns1="http://predic8.com/wsdl/material/ArticleService/1/">
    <ns1:article xmlns:ns1="xmlns:ns1='http://predic8.com/material/1/">
        <ns1:id>1</ns1:id>
        <description>bar</description>
        <name>foo</name>
        <ns1:price>
            <amount>00.00</amount>
            <currency>USD</currency>
        </ns1:price>
        <ns1:price>
            <amount>11.11</amount>
            <currency>AUD</currency>
        </ns1:price>
    </ns1:article>
    <ns1:article xmlns:ns1="xmlns:ns1='http://predic8.com/material/1/">
        <ns1:id>2</ns1:id>
        <description>some name</description>
        <name>some description</name>
        <ns1:price>
            <amount>00.01</amount>
            <currency>USD</currency>
        </ns1:price>
        <quality xmlns="my:q">high</quality>
    </ns1:article>
</ns1:create>

产生想要的、正确的结果:

 create, ns1, http://predic8.com/wsdl/material/ArticleService/1/
 article, ns1, xmlns:ns1='http://predic8.com/material/1/
 id, ns1, xmlns:ns1='http://predic8.com/material/1/
 price, ns1, xmlns:ns1='http://predic8.com/material/1/
 quality, , my:q

进一步的轻微改进也是为属性名称生成命名空间数据:

A further, slight improvement is also to produce the namespace data for attribute names:

distinct-values(//(*|@*)[namespace-uri()]
                    /concat(if(. intersect ../@*)
                              then '@'
                              else (),
                            local-name(),
                            ', ',
                            substring-before(name(), ':'),
                            ', ',
                            namespace-uri(),
                            '&#xA;'
                            )
                )

当在以下 XML 文档中计算此 XPath 表达式时(前一个(以上)在其中一个 文章上添加了 xml:lang 属性 元素):

When this XPath expression is evaluated on the following XML document (the previous one (above) with added an xml:lang attribute on one of the article elements):

<ns1:create xmlns:ns1="http://predic8.com/wsdl/material/ArticleService/1/">
    <ns1:article xml:lang="en-us" xmlns:ns1="xmlns:ns1='http://predic8.com/material/1/">
        <ns1:id>1</ns1:id>
        <description>bar</description>
        <name>foo</name>
        <ns1:price>
            <amount>00.00</amount>
            <currency>USD</currency>
        </ns1:price>
        <ns1:price>
            <amount>11.11</amount>
            <currency>AUD</currency>
        </ns1:price>
    </ns1:article>
    <ns1:article xmlns:ns1="xmlns:ns1='http://predic8.com/material/1/">
        <ns1:id>2</ns1:id>
        <description>some name</description>
        <name>some description</name>
        <ns1:price>
            <amount>00.01</amount>
            <currency>USD</currency>
        </ns1:price>
        <quality xmlns="my:q">high</quality>
    </ns1:article>
</ns1:create>

再次产生正确的结果:

 create, ns1, http://predic8.com/wsdl/material/ArticleService/1/
 article, ns1, xmlns:ns1='http://predic8.com/material/1/
 @lang, xml, http://www.w3.org/XML/1998/namespace
 id, ns1, xmlns:ns1='http://predic8.com/material/1/
 price, ns1, xmlns:ns1='http://predic8.com/material/1/
 quality, , my:q

这篇关于解析 XML 文件以获取所有 Namespace 信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆