Использование XML пространства имен с XmlSlurper в Groovy - как правильно запросить путь? - PullRequest
1 голос
/ 26 марта 2020

У меня есть следующий образец xml:

<root>

<table xmlns:h="http://www.w3.org/TR/html4/">
  <tr>
    <td>Apples</td>
    <td>Bananas</td>
  </tr>
</table>

<table xmlns:f="https://www.w3schools.com/furniture">
  <name>African Coffee Table</name>
  <width>80</width>
  <length>120</length>
</table>

</root>
def slurper = new XmlSlurper().parseText(someXMLText)
def hNs = new groovy.xml.Namespace(
                    "http://www.w3.org/TR/html4/", 'h')
def fNs = new groovy.xml.Namespace(
                    "https://www.w3schools.com/furniture", 'h')
println slurper.root[hNs.table].tr.td //not giving any response

Поскольку есть два табличных тега, имеющих разные теги. Как получить значение Apples под тегом, используя gpath, используя пространство имен.

1 Ответ

2 голосов
/ 26 марта 2020

Вы используете документ XML неправильно. Когда вы определяете пространство имен, например xmlns:h="http://www.w3.org/TR/html4/", вы создаете префикс, который должен использоваться явно. В противном случае вы не сможете запросить документ с использованием этого префикса, если он не назначен ни одному узлу. Вам нужно будет присвоить его как минимум тегу table, чтобы использовать его.

<h:table xmlns:h="http://www.w3.org/TR/html4/">
  <tr>
    <td>Apples</td>
    <td>Bananas</td>
  </tr>
</h:table>

Однако, если вы хотите создать пространство имен по умолчанию для каждого узла table (и его дочерних элементов) узлы), вам нужно пропустить префикс и определить пространство имен без него.

<table xmlns="http://www.w3.org/TR/html4/">
  <tr>
    <td>Apples</td>
    <td>Bananas</td>
  </tr>
</table>

Найдите небольшую разницу - во втором примере мы определили пространство имен с атрибутом xmlns, а не с xmlns:h. как в предыдущем случае.

Когда вы используете пространства имен по умолчанию, вы можете использовать метод declareNamespace, чтобы определить префиксы для пространств имен по умолчанию. Это позволяет вам использовать селектор типа h:table, который ссылается на тег table в пространстве имен, определенный префиксом h в объявленной карте пространств имен. Рассмотрим следующий пример:

def source = '''<root>

<table xmlns="http://www.w3.org/TR/html4/">
  <tr>
    <td>Apples</td>
    <td>Bananas</td>
  </tr>
</table>

<table xmlns="https://www.w3schools.com/furniture">
  <name>African Coffee Table</name>
  <width>80</width>
  <length>120</length>
</table>

</root>'''

def root = new XmlSlurper().parseText(source).declareNamespace([
    h: "http://www.w3.org/TR/html4/", 
    f: "https://www.w3schools.com/furniture"
])

assert root."h:table".tr.td.first().text() == "Apples"
assert root."h:table".tr.td.last().text() == "Bananas"
assert root."f:table".width.toInteger() == 80

В этом примере мы используем документ XML, который определяет два разных пространства имен по умолчанию для тегов table. С помощью метода declareNamespace мы можем определить префиксы для этих пространств имен, чтобы мы могли использовать префикс в селекторе тегов.

Если по какой-то причине вам необходимо определить пространство имен с префиксом в table Уровень узла, вы должны использовать этот префикс по крайней мере на верхнем уровне.

def source = '''<root>

<h:table xmlns:h="http://www.w3.org/TR/html4/">
  <tr>
    <td>Apples</td>
    <td>Bananas</td>
  </tr>
</h:table>

<f:table xmlns:f="https://www.w3schools.com/furniture">
  <name>African Coffee Table</name>
  <width>80</width>
  <length>120</length>
</f:table>

</root>'''

def root = new XmlSlurper().parseText(source).declareNamespace([
    h: "http://www.w3.org/TR/html4/",
    f: "https://www.w3schools.com/furniture"
])

assert root."h:table".tr.td.first().text() == "Apples"
assert root."h:table".tr.td.last().text() == "Bananas"
assert root."f:table".width.toInteger() == 80

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...