2008-11-04 2 views
10

Отказ от ответственности: следующее против греха против XML. Вот почему я пытаюсь изменить его с помощью XSLT :)Сохранение атрибута whitespace

Мой XML в настоящее время выглядит следующим образом:

<root> 
    <object name="blarg" property1="shablarg" property2="werg".../> 
    <object name="yetanotherobject" .../> 
</root> 

Да, я ставлю все текстовые данные в атрибутах. Я надеюсь, что XSLT может спасти меня; Я хочу, чтобы перейти к чему-то вроде этого:

<root> 
    <object> 
     <name>blarg</name> 
     <property1>shablarg</name> 
     ... 
    </object> 
    <object> 
     ... 
    </object> 
</root> 

Я на самом деле получил все это работает до сих пор, за исключением того, что мои грехи против XML были больше ... исключительны. Некоторые теги выглядеть следующим образом:

<object description = "This is the first line 

This is the third line. That second line full of whitespace is meaningful"/> 

Я использую xsltproc под Linux, но это, кажется, не имеют каких-либо опций для сохранения пробелов. Я попытался использовать xsl: preserve-space и xml: space = "сохранить" безрезультатно. Кажется, что каждый найденный параметр применяется для хранения пробелов внутри самих элементов, но не для атрибутов. Каждый раз, выше получает изменено на:

 
This is the first line This is the third line. That second line full of whitespace is meaningful 

Таким образом, вопрос, могу ли я сохранить атрибут пробелы?

+0

Вы должны заменить свои белые-пространства с объектными ссылками для внутреннего значения attribe, как заменить `<Описание объекта =" первый line` \ п ` следующая строка "/>` с `<описание объекта =" первая строка следующая строка "/>`. Нормализация значения атрибута (3.3.3) тогда зависит от типа атрибута, который я считаю `CDATA` defatult. Однако я думаю, что вы можете заставить его использовать ` '>` - может быть или не быть правильным. Тогда, если у вас есть XSL, вам нужно будет вручную обрабатывать пустое пространство, я сделал так же, как `string-join()` и `tokenize()`. – n611x007 2015-04-21 18:11:53

+0

*** Это можно сделать. *** Вы можете получить полный пример ([SSCCE] (http://www.sscce.org/ «Short, Self Contained, Correct (Compilable), Example»)) из мой ответ на другой вопрос: http://stackoverflow.com/a/29780972/611007 (Как я объяснял выше, это не так, как вы пытаетесь это сделать, но в конце концов, он будет работать так, как вы хотели бы.) – n611x007 2015-04-21 20:05:15

+0

связанные с: https://stackoverflow.com/questions/449627/ - , связанные с: https://stackoverflow.com/questions/2004386/ - , связанные с: https://stackoverflow.com/questions/1289524/ – n611x007 2015-04-22 10:58:44

ответ

5

Это на самом деле сырая проблема синтаксического анализа XML, а не то, что XSLT может вам помочь. XML-синтаксис должен преобразовывать символы новой строки в значение этого атрибута в пробелы в соответствии с «3.3.3 Нормализация атрибутов» в стандарте XML. Итак, все, что читает ваши атрибуты описания и сохраняет символы новой строки, делает это неправильно.

Возможно, вы сможете восстановить символы новой строки, предварительно обработав XML, чтобы избежать новых строк до & # 10; символьные ссылки, если у вас также нет новых строк, в которых запрещены символы charrefs, например, внутри тегов. Charrefs должен выжить как контрольные символы до значения атрибута, где затем вы можете превратить их в текстовые узлы.

+1

Я не уверен, что это сработает. Charrefs заменяются байтами, которые они представляют процессором XML, и поэтому charref, ссылающийся на символ пробела (например, LINE FEED), будет нормализован как пробел. – ChuckB 2008-11-04 17:03:55

3

В соответствии с Annotated XML Spec пробел в значениях атрибутов нормализуется процессором XML (см. Аннотацию (T) в разделе 3.3.3). Таким образом, похоже, что ответ, вероятно, нет.

+0

, если вы можете управлять своим процессором xml. – n611x007 2015-04-21 20:13:06

1

Как указывали другие, спецификация XML не позволяет сохранять пробелы в атрибутах. На самом деле, это один из немногих различий между тем, что вы можете делать с атрибутами и элементами (другое главное, что элементы могут содержать другие теги, а атрибуты не могут).

Сначала вы должны обработать файл за пределами XML, чтобы сохранить пробелы.

0

Если вы можете контролировать свой XML-процессор, вы можете это сделать.

Из моего other answer (который имеет много ссылок, связанных):

, если у вас есть XML как

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE elemke [ 
<!ATTLIST brush wood CDATA #REQUIRED> 
]> 

<elemke> 
<brush wood="guy&#xA;threep"/> 
</elemke> 

и XSL как

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template name="split"> 
    <xsl:param name="list"  select="''" /> 
    <xsl:param name="separator" select="'&#xA;'" /> 
    <xsl:if test="not($list = '' or $separator = '')"> 
    <xsl:variable name="head" select="substring-before(concat($list, $separator), $separator)" /> 
    <xsl:variable name="tail" select="substring-after($list, $separator)" /> 

    <xsl:value-of select="$head"/> 
    <br/><xsl:text>&#xA;</xsl:text> 
    <xsl:call-template name="split"> 
     <xsl:with-param name="list"  select="$tail" /> 
     <xsl:with-param name="separator" select="$separator" /> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 


<xsl:template match="brush"> 
    <html> 
    <xsl:call-template name="split"> 
    <xsl:with-param name="list" select="@wood"/> 
    </xsl:call-template> 
    </html> 
</xsl:template> 

</xsl:stylesheet> 

вы можете получить HTML, как:

<html>guy<br> 
    threep<br> 

</html> 

как испытано/производится с процессором, как эта saxon командной строки:

java -jar saxon9he.jar -s:in.xml -xsl:in.xsl -o:out.html