質問

Is it possible to write this test more generally. I´ve sat on it for hours and I can´t figure out :D.

 <pattern>
            <title>Pravidla pro měnu(CZK/USD)</title>
            <rule context="/o:objednávka/o:položky">
                <report test="(contains(o:položka[1]/o:cena/@měna,'CZK') and 
                    contains(o:položka[2]/o:cena/@měna,'USD'))or(contains(o:položka[2]/o:cena/@měna,'CZK') and 
                    contains(o:položka[1]/o:cena/@měna,'USD'))">V objednávce 
                    musí být jen jedna měna.</report>     
            </rule>

XML document

   <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="cssTrans.css" type="text/css" ?>
<?xml-model href="objednavka.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<objednávka xmlns="urn:x-eshop:document-schemas:purchase-order">
    <položky>
        <položka kód="a">
            <název>Sekačka na trávu</název>
            <počet mj="ks">1</počet>
            <cena měna="USD">0.9</cena>
            <popis>http://example.org/sekacka.html</popis>
        </položka>
        <položka kód="d">
            <název>Travní semeno</název>
            <počet mj="kg">2.5</počet>
            <cena měna="CZK">18001</cena>
        </položka>
    </položky>
</objednávka>
役に立ちましたか?

解決

Looking at your rule and your instance document, I strongly suspect that you don't want a "contains" test but rather an "=" test. People often imagine that the English phrase "attribute contains value" should translate to XPath contains(@att, 'val'), but that's wrong; it should be @att = 'val'.

I think the constraint you are trying to express is that there are two položka elements and in one of them, the cena/@měna attribute has the value USD, and in the other, it has the value CZK. I would express that as

o:položka/o:cena/@měna ='CZK' and o:položka/o:cena/@měna = 'USD'

remembering that in XPath, "=" is existential: a/b/c='USD' means that at least one node selected by a/b/c has the value 'USD'.

他のヒント

Use:

contains('USD|CZK|USD', string-join(o:položka/o:cena/@měna, '|'))

XSLT 2.0 - based verification:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:o="urn:x-eshop:document-schemas:purchase-order">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/o:objednávka/o:položky">
  <xsl:sequence select=
  "contains('USD|CZK|USD', string-join(o:položka/o:cena/@měna, '|'))"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<objednávka xmlns="urn:x-eshop:document-schemas:purchase-order">
    <položky>
        <položka kód="a">
            <název>Sekačka na trávu</název>
            <počet mj="ks">1</počet>
            <cena měna="USD">0.9</cena>
            <popis>http://example.org/sekacka.html</popis>
        </položka>
        <položka kód="d">
            <název>Travní semeno</název>
            <počet mj="kg">2.5</počet>
            <cena měna="CZK">18001</cena>
        </položka>
    </položky>
</objednávka>

the XPath expression is evaluated and the result of this evaluation is copied to the output:

true

If the same expression is evaluated on this XML document:

<objednávka xmlns="urn:x-eshop:document-schemas:purchase-order">
    <položky>
        <položka kód="a">
            <název>Sekačka na trávu</název>
            <počet mj="ks">1</počet>
            <cena měna="USD">0.9</cena>
            <popis>http://example.org/sekacka.html</popis>
        </položka>
        <položka kód="d">
            <název>Travní semeno</název>
            <počet mj="kg">2.5</počet>
            <cena měna="USD">18001</cena>
        </položka>
    </položky>
</objednávka>

then again the correct result is produced:

false
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top