XSL — Не удается добавить пространство имен к корневому узлу

#xslt #html-agility-pack

#xslt #html-agility-pack

Вопрос:

У меня есть html, я хочу разобрать его в xml, используя библиотеку html-agility-pack. Вот xsl:

 <?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
  <xsl:template match="/">
    <BusinessDetail>
      <Name>
        <xsl:value-of select="//span[@class='pp-place-title']/span" />
      </Name>
      <Address>
        <xsl:value-of select="//span[@class='pp-headline-item pp-headline-address']/span"/>
      </Address>
      ...
    </BusinessDetail>
  </xsl:template>
</xsl:stylesheet>
  

Я просто хочу добавить пространство имен к корневому узлу. Ожидаемый результат — это:

 <BusinessDetail xmlns:g="http://myurl.com">
  <Name>
    ...
  </Name>
  ..
</BusinessDetail>
  

Так что измените мой xls на:

 <?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
  <xsl:template match="/">
    <BusinessDetail xmlns:g="http://myurl.com">
      <Name>
        <xsl:value-of select="//span[@class='pp-place-title']/span" />
      </Name>
      <Address>
        <xsl:value-of select="//span[@class='pp-headline-item pp-headline-address']/span"/>
      </Address>
      ...
    </BusinessDetail>
  </xsl:template>
</xsl:stylesheet>
  

Но пространство имен не отображается в выходных данных. Здесь что-то не так?

Ответ №1:

Я боюсь, что вывод, который вы пытаетесь создать, не имеет смысла! Подумайте о значении следующего документа:

 <BusinessDetail xmlns:g="http://myurl.com">
  <Name>
    ...
  </Name>
  ..
</BusinessDetail>
  

Вы определяете префикс пространства имен ‘g’ и сопоставляете его с URI http://myurl.com , однако ваш документ не содержит никаких элементов, которые определены как находящиеся в этом пространстве имен! Вывод XSLT совершенно справедливо удаляет это избыточное объявление пространства имен. Вы хотели сделать это вместо:

 <BusinessDetail xmlns="http://myurl.com">
  <Name>
    ...
  </Name>
  ..
</BusinessDetail>
  

Это гарантирует, что BusinessDetail все его дочерние элементы находятся в http://myurl.com пространстве имен.

Ответ №2:

Вам нужно добавить пространство имен в таблицу стилей

 <?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:g="http://myurl.com">
  <xsl:template match="/">
    <BusinessDetail>
      <Name>
        <xsl:value-of select="//span[@class='pp-place-title']/span" />
      </Name>
      <Address>
        <xsl:value-of select="//span[@class='pp-headline-item pp-headline-address']/span"/>
      </Address>
      ...
    </BusinessDetail>
  </xsl:template>
</xsl:stylesheet>
  

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

Комментарии:

1. Привет — Я не согласен, вам не обязательно добавлять пространство имен к элементу xsl:stylesheet, оно может появиться в любом месте документа. Но да, вы правы, если оно не используется, оно не появится в выходных данных!

2. @ColinE возможно, это была неправильная формулировка с моей стороны, подкрепленная примером, который подкрепил этот конкретный случай. По крайней мере, я не пошел с моим первым проектом, который включал псевдоним пространства имен 🙂