XSLT Выбрать значение атрибута узла с другим атрибутом с заданным значением - PullRequest
0 голосов
/ 25 июня 2018

У меня есть большое количество html-файлов, таких как следующий файл 01.html:

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>My Title</title> 
  </head>
  <body>
    <item itemprop="itemprop1" content="content1" /> 
    <item itemprop="itemprop2" content="content2" /> 
    <item itemprop="itemprop3" content="content3" /> 
    <item itemprop="itemprop4" content="content4" />
    <item itemprop="itemprop5" content="content5" />
    <item itemprop="itemprop6" content="content6" />
    <item itemprop="itemprop7" content="content7" />
    <item itemprop="itemprop8" content="content8" />
    <item itemprop="itemprop9" content="content9" />
  </body>
</html>

В каждом html-файле есть только один узел элемента с itemprop = "itemprop1".То же самое для itemprop2, itemprop3 и т. Д.

Я хотел бы получить следующий вывод txt-файла:

content1 | content 5

, который является объединением: 1. значения содержимого атрибута дляэлемент с itemprop = "itemprop1" 2. труба "|"3. значение атрибута содержимого для элемента с itemprop = "itemprop5"

Я запускаю следующий скрипт bash:

xsltproc 01.xslt 01.html >> 02.txt

, где 01.xslt является следующим:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="body">
  <xsl:value-of select="//item[@itemprop='itemprop1']/@content"/>|<xsl:value-of select="item[@itemprop='itemprop5']/@content"/>
 </xsl:template>

</xsl:stylesheet>

К сожалению, это не работает.Что такое правильный файл xslt?

ОБНОВЛЕНИЕ

Это последний рабочий пример.

01.html:

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>My Title</title> 
  </head>
  <body>
    <item itemprop="itemprop1" content="content1" /> 
    <item itemprop="itemprop2" content="content2" /> 
    <item itemprop="itemprop3" content="content3" /> 
    <item itemprop="itemprop4" content="content4" />
    <item itemprop="itemprop5" content="content5" />
    <item itemprop="itemprop6" content="content6" />
    <item itemprop="itemprop7" content="content7" />
    <item itemprop="itemprop8" content="content8" />
    <item itemprop="itemprop9" content="content9" />
  </body>
</html>

01.xslt имеет следующий вид:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes" method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="html">
  <xsl:value-of select="//item[@itemprop='itemprop1']/@content"/>
  <xsl:text>|</xsl:text>
  <xsl:value-of select="//item[@itemprop='itemprop5']/@content"/>
 </xsl:template>

</xsl:stylesheet>

, а вывод 02.txt следующий:

content1|content5

Ответы [ 3 ]

0 голосов
/ 25 июня 2018

Ваша основная проблема с использованием xsltproc заключается в том, что вы пытаетесь обрабатывать HTML вместо XML. Разница заключается в теге <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">, который не является закрытым, и, следовательно, для XSLT-процессора нет действительного XML (что приводит к ошибке). Поэтому добавьте закрывающий символ, чтобы сделать его

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Если вы исправите эту проблему и добавите шаблон, который удаляет «несоответствующие» text() узлы, такие как

<xsl:template match="text()" />

ваш XSLT будет делать то, что вы хотите.

0 голосов
/ 26 июня 2018
<xsl:output method="text" indent="yes"/>
    <xsl:template match="/">
        <xsl:value-of select="html/body/item[@itemprop='itemprop1']/@content"/>|<xsl:value-of select="html/body/item[@itemprop='itemprop5']/@content"/>
    </xsl:template>
0 голосов
/ 25 июня 2018

На самом деле XSTL обрабатывает XML файлы, а не HTML .

Ваш исходный HTML почти соответствует требованиям правильно сформированного XML.Есть только одна ошибка: ваш элемент meta не закрыт, поэтому я изменил его на:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

(добавив / перед закрытием >).В противном случае процессор XSLT отображает сообщение об ошибке (по крайней мере, в моей установке).

Что касается вашего XSLT, я внес несколько исправлений:

  • match="body" изменен наmatch="html",
  • добавлено // во второй xsl:value-of,
  • изменено «голое» | на <xsl:text>|</xsl:text>, только для удобства чтения (более длинные строки не виднына меньших мониторах),
  • добавлено <xsl:output method="text"/>, поскольку ваш вывод не выглядит как XML.

Последние 2 изменения являются необязательными, их можно игнорировать.

Таким образом, весь сценарий может быть таким, как показано ниже:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="html">
    <xsl:value-of select="//item[@itemprop='itemprop1']/@content"/>
    <xsl:text>|</xsl:text>
    <xsl:value-of select="//item[@itemprop='itemprop5']/@content"/>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...