Общая сортировка XML через XSLT, применяемая Java? - PullRequest
0 голосов
/ 19 сентября 2009

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

Я собрал рабочую таблицу стилей, но мне нужно жестко закодировать вход для всех узлов-братьев в узлы, по которым я сортирую. У меня нет официальной схемы, и я не могу быть уверен, что она не изменится. Я хотел бы иметь возможность создать более общую таблицу стилей, которая будет выводить несортированные узлы без этих явных вызовов.

Возможно ли это?

Мой код Java для преобразования XML:

String input = "C:\\presort.xml";
String output = "C:\\postsort.xml";
String xsl = "C:\\sort.xsl"
Document dom;

try
{
 dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
 Element e = dom.getDocumentElement();

 Transformer transform = TransformerFactory.newInstance().newTransformer(
   new StreamSource( new File(xsl) ));
 StreamResult result = new StreamResult(new File(output));
 transform.transform(new DOMSource(dom), result);
} 
catch (Exception e)
{
 e.printStackTrace();
}    

Мой XML:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <Person id="1">
    <Base>true</Base>
    <Description>something</Description>
    <Name>Vin Vinigar</Name>
    <Privileges>
      <Privilige id="340">
        <Permission>2</Permission>
        <Job id="dontsort" />
      </Privilige>
      <Privilige id="11">
        <Permission>3</Permission>
        <Job id="dontsort" />
      </Privilige>
      <Privilige id="1011">
        <Permission>1</Permission>
        <Job id="2342" />
      </Privilige>
    </Privileges>
  </Person>

  <Person id="f32">
    <Base>true</Base>
    <Description>Here be dragons</Description>
    <Name>John Doe</Name>
    <Privileges>
      <Privilige id="23a">
        <Permission>2</Permission>
        <Job id="a2a" />
      </Privilige>
    </Privileges>
  </Person>

  <Person id="22">
    <PossibleUnknownTagHere>something</PossibleUnknownTagHere>
    <Name>Han Solo</Name>
    <Privileges>
      <Privilige id="23a">
        <Permission>3</Permission>
        <Job id="a2a" />
      </Privilige>
    </Privileges>
  </Person>

</root>

Моя таблица стилей:

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

    <xsl:template match="root|@*">
        <xsl:copy >
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="Person">
                <xsl:sort select="@id" order="ascending" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Person">
        <xsl:copy >
            <xsl:apply-templates select="@*" />

            <!-- Works but requies a template for each sibling element -->
            <xsl:apply-templates select="Base" />
            <xsl:apply-templates select="Description" />
            <xsl:apply-templates select="Name" />

            <!-- I'd like to do something like this -->
            <!--
            <xsl:choose>
                <xsl:when test="not(Privileges)">
                    <xsl:apply-templates select="." />
                </xsl:when>
            </xsl:choose>
            -->

            <xsl:apply-templates select="Privileges" />
        </xsl:copy>
    </xsl:template>

    <!-- I'd like to remove the need for these 3 explicity copies -->
    <xsl:template match="Base">
        <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="Description">
        <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="Name">
        <xsl:copy-of select="."/>
    </xsl:template>

    <xsl:template match="Privileges">
        <xsl:copy >
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="Privilege">
                <xsl:sort select="@id" order="ascending" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Privilege">
        <xsl:copy-of select="."/>
    </xsl:template>

</xsl:stylesheet>

1 Ответ

2 голосов
/ 19 сентября 2009
<xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates />
    </xsl:copy>
<xsl:template>

<xsl:template match="root">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:apply-templates select="Person">
            <xsl:sort select="@id" order="ascending" />
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="Privileges">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:apply-templates select="Privilege">
            <xsl:sort select="@id" order="ascending" />
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...